module Services where
import Util
import Requests
import Text.JSON
import Data.Map hiding (filter, map)
import Data.List (find)
import System.IO.Error
import Data.Maybe

  
data Action  = Action { actionText, actionID, contextText :: String, actionDone:: Bool }
    deriving (Eq, Show)
data Project = Project { projectName, projectID :: String }
    deriving (Eq, Show)
data Context = Context { contextName, contextID :: String }
    deriving (Eq, Show)


showNextActions = showNextActionsFiltered (const True)

showNextActionsFiltered filtr api_key = do
    Just rsp <- requestNextActions api_key
    putStr . showEnumerated . filter filtr . filter notDone . parseActions $ rsp

showEnumerated :: Displayable a => [a] -> String
showEnumerated items = foldr showsPos "" enumerated 
    where
        showsPos (pos, item) t = shows pos $ ". " ++ displays item ("\n" ++ t)
        enumerated = zip [1..] items

class Displayable a where
    displays :: a -> String -> String

instance Displayable Action where
    displays a s = actionText a ++ s

parseActions ::  String -> [Action]
parseActions = map actionFromJson . jRead

notDone :: Action -> Bool
notDone a = not (actionDone a)

contextsFilter [] _            = True
contextsFilter contexts action = (contextText action) `elem` contexts

actionFromJson :: Map String JsonNode -> Action
actionFromJson m = Action { actionText  = fromJson $ m!"name",
                            actionID    = fromJson $ m!"id",
                            actionDone  = (fromJson (m!"done") :: Int) == 1,
                            contextText = fromJson $ m!"context_name"}

addAction api_key prj ctx name = do
      projects <- getProjects api_key
      let prj_id = projectID . head $ filter ((==prj) . projectName) projects
      contexts <- getContexts api_key
      case find ((==ctx) . contextName) contexts of
            Just context -> do
               let ctx_id = contextID context
               createAction api_key prj_id ctx_id name
            Nothing -> 
               raise $ "no such context: " ++ ctx


getProjects :: String -> IO([Project])
getProjects = fmap (map projFromJson . jRead . fromJust) . requestProjects


getApiKeyFromNozbe :: String -> String -> IO (Maybe String)

getApiKeyFromNozbe email password =
  (flip fmap) (requestApiKey email password) $ (>>=
    \txt -> (jRead txt)!"key")

projFromJson m = Project { projectName = m!"name",
                           projectID = m!"id" }


getContexts :: String -> IO([Context])
getContexts = fmap (map ctxFromJson . jRead . fromJust) . requestContexts


showContexts :: String -> IO()
showContexts api_key = do
    Just rsp <- requestContexts api_key
    let contexts = map ctxFromJson $ jRead rsp
    putStr $ showEnumerated contexts
    

ctxFromJson m = Context { contextName = m!"name",
                          contextID = m!"id" }


instance Displayable Context where
    displays c s = contextName c ++ s

